package dxn.nl.file.center.netty.consumer;

import dxn.nl.file.center.CsCenterNettyConstants;
import dxn.nl.file.center.SocketManager;
import dxn.nl.file.center.netty.client.ClientSocketManager;
import dxn.nl.file.client.model.codec.MessageCodeUtil;
import dxn.nl.file.client.model.dto.TransferMessageDto;
import dxn.nl.file.client.model.enums.ExportDealResultTypeEnum;
import dxn.nl.file.client.model.enums.ExportMessageTypeEnum;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.SocketChannel;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConsumerNettyServerHandler extends SimpleChannelInboundHandler<TransferMessageDto> {
    private static final Logger log = LoggerFactory.getLogger(ConsumerNettyServerHandler.class);

    @Override
    protected void channelRead0(ChannelHandlerContext context, TransferMessageDto dto) {
        SocketChannel socketChannel = (SocketChannel) context.channel();
        //String message = (String)obj;

        try{
            int type = dto.getType();

            String sessionId = socketChannel.attr(CsCenterNettyConstants.APP_SESSION_ID).get();

            // 非注册消息，如果没有appid或者sessionId,则连接无效，断开连接
            if (type != ExportMessageTypeEnum.server_connect.code)
            {

                if(StringUtils.isBlank(sessionId))
                {
                    log.info("sessionId: {} 为空",sessionId);
                    socketChannel.close();
                    return;
                }

                if(!ConsumerSocketManager.contains(sessionId))
                {
                    log.info("sessionId: {} ,未能成功注册",sessionId);
                    socketChannel.close();
                    return;
                }
            }

            if(type == ExportMessageTypeEnum.heartbeat.code)
            {
                ConsumerSocketManager.refreshClient(sessionId);
                // 心跳包,刷新时间,直接回写
                SocketManager.sendNoResult(socketChannel, dto);
                return ;
            }
            dealData(socketChannel,dto,sessionId);
        }
        catch (Exception ex)
        {
            log.error("",ex);
        }
        finally {
            //ReferenceCountUtil.release(byteBuf);
        }
    }

    @Override
    public void handlerAdded(ChannelHandlerContext ctx) {
        log.info(">>>>>>>>连接");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) {
        SocketChannel socketChannel = (SocketChannel) ctx.channel();
        String sessionId = socketChannel.attr(CsCenterNettyConstants.APP_SESSION_ID).get();
        if(sessionId==null)
        {
            return ;
        }
        ConsumerSocketManager.removeClient(sessionId);
        log.info(socketChannel.localAddress()+">>>>>>>>退出");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("",cause);
        ctx.close();
    }

    private void dealData(SocketChannel socketChannel, TransferMessageDto message,String sessionId) {
        //log.info(">>>>>>>>>>>服务端接收到客户端的消息：{}",obj);
        int type = message.getType();
        // 如果是连接，记录socket
        if (type == ExportMessageTypeEnum.server_connect.code) {
            String sessionRegisterId = message.getConfig().getSessionId();
            ConsumerSocketManager.addClient(sessionRegisterId,socketChannel);
            log.info("处理服务端注册 {} {}", socketChannel.remoteAddress(),sessionId);
            return;
        }

        // 客户端发出 申请和发送数据
        if (ExportMessageTypeEnum.consumer_heart_beat.code == type) {
            ConsumerSocketManager.refreshClient(sessionId);
            return;
        }

        // 客户端发出 申请和发送数据
        if (ExportMessageTypeEnum.consumer_query_data.code == type) {
            // 查询
            //
            ConsumerSocketManager.refreshClient(sessionId);
            return;
        }

        // 客户端发出 申请和发送数据
        if (ExportMessageTypeEnum.consumer_deal_result.code == type) {
            ConsumerSocketManager.refreshClient(sessionId);
            return;
        }

        // 记录是哪个服务端地址处理的结果，便于客户端反向推送使用
        message.getConfig().setDealSession(sessionId);

        // 如果是处理结果的话，直接给future赋值，结束
        if (StringUtils.isBlank(message.getConfig().getAppId())) {
            // from来源客户端没有了，就没有办法，发送给原来的客户端了
            SocketManager.sendErrorNoResult(socketChannel, message, "appId不能为空");
            return;
        }

        if (ExportMessageTypeEnum.query_head.code != type
                && ExportMessageTypeEnum.query_data.code != type)
        {
            if (StringUtils.isBlank(message.getConfig().getClient())) {
                // from来源客户端没有了，就没有办法，发送给原来的客户端了
                SocketManager.sendErrorNoResult(socketChannel, message, "client不能为空");
                return;
            }
        }

        // 找到对应的源数据发送方
        SocketChannel clientChannel = ClientSocketManager.getClientChannel(message.getConfig().getAppId(), message.getConfig().getClient());

        if (clientChannel != null) {
            SocketManager.sendNoResult(clientChannel, message);
        } else {
            SocketManager.sendErrorNoResult(socketChannel, message, ExportDealResultTypeEnum.nextIp.code,"未找到对应form客户端");
        }
    }
}